home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / ASTExpression.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  18.6 KB  |  630 lines  |  [TEXT/KAHL]

  1. /* ASTExpression.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "ASTExpression.h"
  31. #include "TrashTracker.h"
  32. #include "Memory.h"
  33. #include "ASTArrayDeclaration.h"
  34. #include "ASTAssignment.h"
  35. #include "ASTBinaryOperator.h"
  36. #include "ASTConditional.h"
  37. #include "ASTExpressionList.h"
  38. #include "ASTFuncCall.h"
  39. #include "ASTLoop.h"
  40. #include "ASTOperand.h"
  41. #include "ASTUnaryOperator.h"
  42. #include "ASTVariableDeclaration.h"
  43. #include "ASTErrorForm.h"
  44. #include "ASTWaveGetter.h"
  45. #include "SymbolTableEntry.h"
  46.  
  47.  
  48. struct ASTExpressionRec
  49.     {
  50.         ExprTypes                        ElementType;
  51.         DataTypes                        WhatIsTheExpressionType;
  52.         long                                LineNumber;
  53.         union
  54.             {
  55.                 ASTArrayDeclRec*        ArrayDeclaration;
  56.                 ASTAssignRec*                Assignment;
  57.                 ASTBinaryOpRec*            BinaryOperator;
  58.                 ASTCondRec*                    Conditional;
  59.                 ASTExprListRec*            ExpressionList;
  60.                 ASTFuncCallRec*            FunctionCall;
  61.                 ASTLoopRec*                    Loop;
  62.                 ASTOperandRec*            Operand;
  63.                 ASTUnaryOpRec*            UnaryOperator;
  64.                 ASTVarDeclRec*            VariableDeclaration;
  65.                 ASTErrorFormRec*        ErrorForm;
  66.                 ASTWaveGetterRec*        WaveGetter;
  67.             } u;
  68.     };
  69.  
  70.  
  71. /* construct a generic expression around an array declaration */
  72. ASTExpressionRec*        NewExprArrayDecl(struct ASTArrayDeclRec* TheArrayDeclaration,
  73.                                             struct TrashTrackRec* TrashTracker, long TheLineNumber)
  74.     {
  75.         ASTExpressionRec*    Expr;
  76.  
  77.         CheckPtrExistence(TheArrayDeclaration);
  78.         CheckPtrExistence(TrashTracker);
  79.         Expr = (ASTExpressionRec*)AllocTrackedBlock(sizeof(ASTExpressionRec),TrashTracker);
  80.         if (Expr == NIL)
  81.             {
  82.                 return NIL;
  83.             }
  84.         SetTag(Expr,"ASTExpressionRec: NewExprArrayDecl");
  85.  
  86.         Expr->ElementType = eExprArrayDeclaration;
  87.         Expr->u.ArrayDeclaration = TheArrayDeclaration;
  88.         Expr->LineNumber = TheLineNumber;
  89.  
  90.         return Expr;
  91.     }
  92.  
  93.  
  94. /* construct a generic expression around an assignment statement */
  95. ASTExpressionRec*        NewExprAssignment(struct ASTAssignRec* TheAssignment,
  96.                                             struct TrashTrackRec* TrashTracker, long TheLineNumber)
  97.     {
  98.         ASTExpressionRec*    Expr;
  99.  
  100.         CheckPtrExistence(TheAssignment);
  101.         CheckPtrExistence(TrashTracker);
  102.         Expr = (ASTExpressionRec*)AllocTrackedBlock(sizeof(ASTExpressionRec),TrashTracker);
  103.         if (Expr == NIL)
  104.             {
  105.                 return NIL;
  106.             }
  107.         SetTag(Expr,"ASTExpressionRec: NewExprAssignment");
  108.  
  109.         Expr->ElementType = eExprAssignment;
  110.         Expr->u.Assignment = TheAssignment;
  111.         Expr->LineNumber = TheLineNumber;
  112.  
  113.         return Expr;
  114.     }
  115.  
  116.  
  117. /* construct a generic expression around a binary operator */
  118. ASTExpressionRec*        NewExprBinaryOperator(struct ASTBinaryOpRec* TheBinaryOperator,
  119.                                             struct TrashTrackRec* TrashTracker, long TheLineNumber)
  120.     {
  121.         ASTExpressionRec*    Expr;
  122.  
  123.         CheckPtrExistence(TheBinaryOperator);
  124.         CheckPtrExistence(TrashTracker);
  125.         Expr = (ASTExpressionRec*)AllocTrackedBlock(sizeof(ASTExpressionRec),TrashTracker);
  126.         if (Expr == NIL)
  127.             {
  128.                 return NIL;
  129.             }
  130.         SetTag(Expr,"ASTExpressionRec: NewExprBinaryOperator");
  131.  
  132.         Expr->ElementType = eExprBinaryOperator;
  133.         Expr->u.BinaryOperator = TheBinaryOperator;
  134.         Expr->LineNumber = TheLineNumber;
  135.  
  136.         return Expr;
  137.     }
  138.  
  139.  
  140. /* construct a generic expression around a conditional. */
  141. ASTExpressionRec*        NewExprConditional(struct ASTCondRec* TheConditional,
  142.                                             struct TrashTrackRec* TrashTracker, long TheLineNumber)
  143.     {
  144.         ASTExpressionRec*    Expr;
  145.  
  146.         CheckPtrExistence(TheConditional);
  147.         CheckPtrExistence(TrashTracker);
  148.         Expr = (ASTExpressionRec*)AllocTrackedBlock(sizeof(ASTExpressionRec),TrashTracker);
  149.         if (Expr == NIL)
  150.             {
  151.                 return NIL;
  152.             }
  153.         SetTag(Expr,"ASTExpressionRec: NewExprConditional");
  154.  
  155.         Expr->ElementType = eExprConditional;
  156.         Expr->u.Conditional = TheConditional;
  157.         Expr->LineNumber = TheLineNumber;
  158.  
  159.         return Expr;
  160.     }
  161.  
  162.  
  163. /* construct a generic expression around a list of expressions. */
  164. ASTExpressionRec*        NewExprSequence(struct ASTExprListRec* TheExpressionList,
  165.                                             struct TrashTrackRec* TrashTracker, long TheLineNumber)
  166.     {
  167.         ASTExpressionRec*    Expr;
  168.  
  169.         if (TheExpressionList != NIL)
  170.             {
  171.                 CheckPtrExistence(TheExpressionList);
  172.             }
  173.         CheckPtrExistence(TrashTracker);
  174.         Expr = (ASTExpressionRec*)AllocTrackedBlock(sizeof(ASTExpressionRec),TrashTracker);
  175.         if (Expr == NIL)
  176.             {
  177.                 return NIL;
  178.             }
  179.         SetTag(Expr,"ASTExpressionRec: NewExprSequence");
  180.  
  181.         Expr->ElementType = eExprExpressionList;
  182.         Expr->u.ExpressionList = TheExpressionList;
  183.         Expr->LineNumber = TheLineNumber;
  184.  
  185.         return Expr;
  186.     }
  187.  
  188.  
  189. /* construct a generic expression around a function call */
  190. ASTExpressionRec*        NewExprFunctionCall(struct ASTFuncCallRec* TheFunctionCall,
  191.                                             struct TrashTrackRec* TrashTracker, long TheLineNumber)
  192.     {
  193.         ASTExpressionRec*    Expr;
  194.  
  195.         CheckPtrExistence(TheFunctionCall);
  196.         CheckPtrExistence(TrashTracker);
  197.         Expr = (ASTExpressionRec*)AllocTrackedBlock(sizeof(ASTExpressionRec),TrashTracker);
  198.         if (Expr == NIL)
  199.             {
  200.                 return NIL;
  201.             }
  202.         SetTag(Expr,"ASTExpressionRec: NewExprFunctionCall");
  203.  
  204.         Expr->ElementType = eExprFunctionCall;
  205.         Expr->u.FunctionCall = TheFunctionCall;
  206.         Expr->LineNumber = TheLineNumber;
  207.  
  208.         return Expr;
  209.     }
  210.  
  211.  
  212. /* construct a generic expression around a loop */
  213. ASTExpressionRec*        NewExprLoop(struct ASTLoopRec* TheLoop,
  214.                                             struct TrashTrackRec* TrashTracker, long TheLineNumber)
  215.     {
  216.         ASTExpressionRec*    Expr;
  217.  
  218.         CheckPtrExistence(TheLoop);
  219.         CheckPtrExistence(TrashTracker);
  220.         Expr = (ASTExpressionRec*)AllocTrackedBlock(sizeof(ASTExpressionRec),TrashTracker);
  221.         if (Expr == NIL)
  222.             {
  223.                 return NIL;
  224.             }
  225.         SetTag(Expr,"ASTExpressionRec: NewExprLoop");
  226.  
  227.         Expr->ElementType = eExprLoop;
  228.         Expr->u.Loop = TheLoop;
  229.         Expr->LineNumber = TheLineNumber;
  230.  
  231.         return Expr;
  232.     }
  233.  
  234.  
  235. /* construct a generic expression around an operand */
  236. ASTExpressionRec*        NewExprOperand(struct ASTOperandRec* TheOperand,
  237.                                             struct TrashTrackRec* TrashTracker, long TheLineNumber)
  238.     {
  239.         ASTExpressionRec*    Expr;
  240.  
  241.         CheckPtrExistence(TheOperand);
  242.         CheckPtrExistence(TrashTracker);
  243.         Expr = (ASTExpressionRec*)AllocTrackedBlock(sizeof(ASTExpressionRec),TrashTracker);
  244.         if (Expr == NIL)
  245.             {
  246.                 return NIL;
  247.             }
  248.         SetTag(Expr,"ASTExpressionRec: NewExprOperand");
  249.  
  250.         Expr->ElementType = eExprOperand;
  251.         Expr->u.Operand = TheOperand;
  252.         Expr->LineNumber = TheLineNumber;
  253.  
  254.         return Expr;
  255.     }
  256.  
  257.  
  258. /* construct a generic expression around a unary operator */
  259. ASTExpressionRec*        NewExprUnaryOperator(struct ASTUnaryOpRec* TheUnaryOperator,
  260.                                             struct TrashTrackRec* TrashTracker, long TheLineNumber)
  261.     {
  262.         ASTExpressionRec*    Expr;
  263.  
  264.         CheckPtrExistence(TheUnaryOperator);
  265.         CheckPtrExistence(TrashTracker);
  266.         Expr = (ASTExpressionRec*)AllocTrackedBlock(sizeof(ASTExpressionRec),TrashTracker);
  267.         if (Expr == NIL)
  268.             {
  269.                 return NIL;
  270.             }
  271.         SetTag(Expr,"ASTExpressionRec: NewExprUnaryOperator");
  272.  
  273.         Expr->ElementType = eExprUnaryOperator;
  274.         Expr->u.UnaryOperator = TheUnaryOperator;
  275.         Expr->LineNumber = TheLineNumber;
  276.  
  277.         return Expr;
  278.     }
  279.  
  280.  
  281. /* construct a generic expression around a variable declaration */
  282. ASTExpressionRec*        NewExprVariableDeclaration(struct ASTVarDeclRec* TheVariableDecl,
  283.                                             struct TrashTrackRec* TrashTracker, long TheLineNumber)
  284.     {
  285.         ASTExpressionRec*    Expr;
  286.  
  287.         CheckPtrExistence(TheVariableDecl);
  288.         CheckPtrExistence(TrashTracker);
  289.         Expr = (ASTExpressionRec*)AllocTrackedBlock(sizeof(ASTExpressionRec),TrashTracker);
  290.         if (Expr == NIL)
  291.             {
  292.                 return NIL;
  293.             }
  294.         SetTag(Expr,"ASTExpressionRec: NewExprVariableDeclaration");
  295.  
  296.         Expr->ElementType = eExprVariableDeclaration;
  297.         Expr->u.VariableDeclaration = TheVariableDecl;
  298.         Expr->LineNumber = TheLineNumber;
  299.  
  300.         return Expr;
  301.     }
  302.  
  303.  
  304. /* construct a generic expression around an error form */
  305. ASTExpressionRec*        NewExprErrorForm(struct ASTErrorFormRec* TheErrorForm,
  306.                                             struct TrashTrackRec* TrashTracker, long TheLineNumber)
  307.     {
  308.         ASTExpressionRec*    Expr;
  309.  
  310.         CheckPtrExistence(TheErrorForm);
  311.         CheckPtrExistence(TrashTracker);
  312.         Expr = (ASTExpressionRec*)AllocTrackedBlock(sizeof(ASTExpressionRec),TrashTracker);
  313.         if (Expr == NIL)
  314.             {
  315.                 return NIL;
  316.             }
  317.         SetTag(Expr,"ASTExpressionRec: NewExprErrorForm");
  318.  
  319.         Expr->ElementType = eExprErrorForm;
  320.         Expr->u.ErrorForm = TheErrorForm;
  321.         Expr->LineNumber = TheLineNumber;
  322.  
  323.         return Expr;
  324.     }
  325.  
  326.  
  327. /* construct a generic expression around a wave getter */
  328. ASTExpressionRec*        NewExprWaveGetter(struct ASTWaveGetterRec* TheWaveGetter,
  329.                                             struct TrashTrackRec* TrashTracker, long TheLineNumber)
  330.     {
  331.         ASTExpressionRec*    Expr;
  332.  
  333.         CheckPtrExistence(TheWaveGetter);
  334.         CheckPtrExistence(TrashTracker);
  335.         Expr = (ASTExpressionRec*)AllocTrackedBlock(sizeof(ASTExpressionRec),TrashTracker);
  336.         if (Expr == NIL)
  337.             {
  338.                 return NIL;
  339.             }
  340.         SetTag(Expr,"ASTExpressionRec: NewExprWaveGetter");
  341.  
  342.         Expr->ElementType = eExprWaveGetter;
  343.         Expr->u.WaveGetter = TheWaveGetter;
  344.         Expr->LineNumber = TheLineNumber;
  345.  
  346.         return Expr;
  347.     }
  348.  
  349.  
  350. /* type check an expression.  returns eCompileNoError and the resulting value */
  351. /* type if it checks correctly. */
  352. CompileErrors                TypeCheckExpression(DataTypes* ResultTypeOut,
  353.                                             ASTExpressionRec* TheExpression, long* ErrorLineNumber,
  354.                                             struct TrashTrackRec* TrashTracker)
  355.     {
  356.         CompileErrors            ReturnValue;
  357.  
  358.         CheckPtrExistence(TheExpression);
  359.         CheckPtrExistence(TrashTracker);
  360.  
  361.         switch (TheExpression->ElementType)
  362.             {
  363.                 default:
  364.                     EXECUTE(PRERR(ForceAbort,"TypeCheckExpression:  unknown AST node type"));
  365.                     break;
  366.                 case eExprArrayDeclaration:
  367.                     ReturnValue = TypeCheckArrayConstruction(ResultTypeOut,
  368.                         TheExpression->u.ArrayDeclaration,ErrorLineNumber,TrashTracker);
  369.                     break;
  370.                 case eExprAssignment:
  371.                     ReturnValue = TypeCheckAssignment(ResultTypeOut,TheExpression->u.Assignment,
  372.                         ErrorLineNumber,TrashTracker);
  373.                     break;
  374.                 case eExprBinaryOperator:
  375.                     ReturnValue = TypeCheckBinaryOperator(ResultTypeOut,
  376.                         TheExpression->u.BinaryOperator,ErrorLineNumber,TrashTracker);
  377.                     break;
  378.                 case eExprConditional:
  379.                     ReturnValue = TypeCheckConditional(ResultTypeOut,TheExpression->u.Conditional,
  380.                         ErrorLineNumber,TrashTracker);
  381.                     break;
  382.                 case eExprExpressionList:
  383.                     /* this needs to be done specially */
  384.                     if (TheExpression->u.ExpressionList == NIL)
  385.                         {
  386.                             *ErrorLineNumber = TheExpression->LineNumber;
  387.                             ReturnValue = eCompileVoidExpressionIsNotAllowed;
  388.                         }
  389.                      else
  390.                         {
  391.                             ReturnValue = TypeCheckExprList(ResultTypeOut,
  392.                                 TheExpression->u.ExpressionList,ErrorLineNumber,TrashTracker);
  393.                         }
  394.                     break;
  395.                 case eExprFunctionCall:
  396.                     ReturnValue = TypeCheckFunctionCall(ResultTypeOut,TheExpression->u.FunctionCall,
  397.                         ErrorLineNumber,TrashTracker);
  398.                     break;
  399.                 case eExprLoop:
  400.                     ReturnValue = TypeCheckLoop(ResultTypeOut,TheExpression->u.Loop,ErrorLineNumber,
  401.                         TrashTracker);
  402.                     break;
  403.                 case eExprOperand:
  404.                     ReturnValue = TypeCheckOperand(ResultTypeOut,TheExpression->u.Operand,
  405.                         ErrorLineNumber,TrashTracker);
  406.                     break;
  407.                 case eExprUnaryOperator:
  408.                     ReturnValue = TypeCheckUnaryOperator(ResultTypeOut,
  409.                         TheExpression->u.UnaryOperator,ErrorLineNumber,TrashTracker);
  410.                     break;
  411.                 case eExprVariableDeclaration:
  412.                     ReturnValue = TypeCheckVariableDeclaration(ResultTypeOut,
  413.                         TheExpression->u.VariableDeclaration,ErrorLineNumber,TrashTracker);
  414.                     break;
  415.                 case eExprErrorForm:
  416.                     ReturnValue = TypeCheckErrorForm(ResultTypeOut,TheExpression->u.ErrorForm,
  417.                         ErrorLineNumber,TrashTracker);
  418.                     break;
  419.                 case eExprWaveGetter:
  420.                     ReturnValue = TypeCheckWaveGetter(ResultTypeOut,TheExpression->u.WaveGetter,
  421.                         ErrorLineNumber,TrashTracker);
  422.                     break;
  423.             }
  424.  
  425.         TheExpression->WhatIsTheExpressionType = *ResultTypeOut;
  426.         return ReturnValue;
  427.     }
  428.  
  429.  
  430. /* get a symbol table entry out of an expression.  this is used for getting */
  431. /* function generation stuff. */
  432. CompileErrors                ExpressionGetFunctionCallSymbol(struct SymbolRec** SymbolOut,
  433.                                             ASTExpressionRec* TheExpression)
  434.     {
  435.         SymbolRec*                FunctionThing;
  436.  
  437.         CheckPtrExistence(TheExpression);
  438.         if (TheExpression->ElementType != eExprOperand)
  439.             {
  440.                 return eCompileFunctionIdentifierRequired;
  441.             }
  442.         if (!IsOperandASymbol(TheExpression->u.Operand))
  443.             {
  444.                 return eCompileFunctionIdentifierRequired;
  445.             }
  446.         FunctionThing = GetSymbolFromOperand(TheExpression->u.Operand);
  447.         CheckPtrExistence(FunctionThing);
  448.         if (eSymbolFunction != WhatIsThisSymbol(FunctionThing))
  449.             {
  450.                 return eCompileFunctionIdentifierRequired;
  451.             }
  452.         *SymbolOut = FunctionThing;
  453.         return eCompileNoError;
  454.     }
  455.  
  456.  
  457. /* find out if the expression is a valid lvalue */
  458. MyBoolean                        IsExpressionValidLValue(ASTExpressionRec* TheExpression)
  459.     {
  460.         CheckPtrExistence(TheExpression);
  461.  
  462.         /* to be a valid lvalue, the expression must be one of */
  463.         /*  - variable */
  464.         /*  - array subscription operation */
  465.         switch (TheExpression->ElementType)
  466.             {
  467.                 default:
  468.                     return False;
  469.  
  470.                 case eExprBinaryOperator:
  471.                     return (BinaryOperatorWhichOne(TheExpression->u.BinaryOperator)
  472.                         == eBinaryArraySubscripting);
  473.  
  474.                 case eExprOperand:
  475.                     if (IsOperandASymbol(TheExpression->u.Operand))
  476.                         {
  477.                             SymbolRec*            TheOperandThing;
  478.  
  479.                             TheOperandThing = GetSymbolFromOperand(TheExpression->u.Operand);
  480.                             return WhatIsThisSymbol(TheOperandThing) == eSymbolVariable;
  481.                         }
  482.                      else
  483.                         {
  484.                             return False;
  485.                         }
  486.             }
  487.         EXECUTE(PRERR(ForceAbort,"IsExpressionValidLValue:  control reached end"));
  488.     }
  489.  
  490.  
  491. /* find out what kind of expression it is */
  492. ExprTypes                        WhatKindOfExpressionIsThis(ASTExpressionRec* TheExpression)
  493.     {
  494.         CheckPtrExistence(TheExpression);
  495.         return TheExpression->ElementType;
  496.     }
  497.  
  498.  
  499. /* get the operand from the generic expression */
  500. struct ASTOperandRec*    GetOperandOutOfExpression(ASTExpressionRec* TheExpression)
  501.     {
  502.         CheckPtrExistence(TheExpression);
  503.         ERROR(TheExpression->ElementType != eExprOperand,PRERR(ForceAbort,
  504.             "GetOperandOutOfExpression:  expression isn't an operand"));
  505.         return TheExpression->u.Operand;
  506.     }
  507.  
  508.  
  509. /* get the binary operator out of the generic expression */
  510. struct ASTBinaryOpRec*    GetBinaryOperatorOutOfExpression(ASTExpressionRec* TheExpression)
  511.     {
  512.         CheckPtrExistence(TheExpression);
  513.         ERROR(TheExpression->ElementType != eExprBinaryOperator,PRERR(ForceAbort,
  514.             "GetBinaryOperatorOutOfExpression:  expression isn't an operand"));
  515.         return TheExpression->u.BinaryOperator;
  516.     }
  517.  
  518.  
  519. /* get the type of value that is returned by this expression */
  520. DataTypes                        GetExpressionsResultantType(ASTExpressionRec* TheExpression)
  521.     {
  522.         CheckPtrExistence(TheExpression);
  523.         return TheExpression->WhatIsTheExpressionType;
  524.     }
  525.  
  526.  
  527. /* generate code for an expression.  returns True if successful, or False if it fails. */
  528. MyBoolean                        CodeGenExpression(struct PcodeRec* FuncCode,
  529.                                             long* StackDepthParam, ASTExpressionRec* Expression)
  530.     {
  531.         long                            StackDepth;
  532.  
  533.         CheckPtrExistence(FuncCode);
  534.         CheckPtrExistence(Expression);
  535.         StackDepth = *StackDepthParam;
  536.  
  537.         switch (Expression->ElementType)
  538.             {
  539.                 default:
  540.                     EXECUTE(PRERR(ForceAbort,"CodeGenExpression:  unknown expression type"));
  541.                     break;
  542.                 case eExprArrayDeclaration:
  543.                     if (!CodeGenArrayConstruction(FuncCode,&StackDepth,
  544.                         Expression->u.ArrayDeclaration))
  545.                         {
  546.                             return False;
  547.                         }
  548.                     break;
  549.                 case eExprAssignment:
  550.                     if (!CodeGenAssignment(FuncCode,&StackDepth,Expression->u.Assignment))
  551.                         {
  552.                             return False;
  553.                         }
  554.                     break;
  555.                 case eExprBinaryOperator:
  556.                     if (!CodeGenBinaryOperator(FuncCode,&StackDepth,Expression->u.BinaryOperator))
  557.                         {
  558.                             return False;
  559.                         }
  560.                     break;
  561.                 case eExprConditional:
  562.                     if (!CodeGenConditional(FuncCode,&StackDepth,Expression->u.Conditional))
  563.                         {
  564.                             return False;
  565.                         }
  566.                     break;
  567.                 case eExprExpressionList:
  568.                     if (!CodeGenExpressionListSequence(FuncCode,&StackDepth,
  569.                         Expression->u.ExpressionList))
  570.                         {
  571.                             return False;
  572.                         }
  573.                     break;
  574.                 case eExprFunctionCall:
  575.                     if (!CodeGenFunctionCall(FuncCode,&StackDepth,Expression->u.FunctionCall))
  576.                         {
  577.                             return False;
  578.                         }
  579.                     break;
  580.                 case eExprLoop:
  581.                     if (!CodeGenLoop(FuncCode,&StackDepth,Expression->u.Loop))
  582.                         {
  583.                             return False;
  584.                         }
  585.                     break;
  586.                 case eExprOperand:
  587.                     if (!CodeGenOperand(FuncCode,&StackDepth,Expression->u.Operand))
  588.                         {
  589.                             return False;
  590.                         }
  591.                     break;
  592.                 case eExprUnaryOperator:
  593.                     if (!CodeGenUnaryOperator(FuncCode,&StackDepth,Expression->u.UnaryOperator))
  594.                         {
  595.                             return False;
  596.                         }
  597.                     break;
  598.                 case eExprVariableDeclaration:
  599.                     if (!CodeGenVarDecl(FuncCode,&StackDepth,Expression->u.VariableDeclaration))
  600.                         {
  601.                             return False;
  602.                         }
  603.                     break;
  604.                 case eExprErrorForm:
  605.                     if (!CodeGenErrorForm(FuncCode,&StackDepth,Expression->u.ErrorForm))
  606.                         {
  607.                             return False;
  608.                         }
  609.                     break;
  610.                 case eExprWaveGetter:
  611.                     if (!CodeGenWaveGetter(FuncCode,&StackDepth,Expression->u.WaveGetter))
  612.                         {
  613.                             return False;
  614.                         }
  615.                     break;
  616.             }
  617.         ERROR(
  618.             (((Expression->ElementType != eExprVariableDeclaration)
  619.                 && (Expression->ElementType != eExprArrayDeclaration))
  620.                 && (StackDepth != *StackDepthParam + 1))
  621.             ||
  622.             (((Expression->ElementType == eExprVariableDeclaration)
  623.                 || (Expression->ElementType == eExprArrayDeclaration))
  624.                 && (StackDepth != *StackDepthParam + 2)),
  625.             PRERR(ForceAbort,"CodeGenExpression:  stack depth error"));
  626.  
  627.         *StackDepthParam = StackDepth;
  628.         return True;
  629.     }
  630.